/*
 * ModificableTableModel.java
 *
 * Created on 21 de mayo de 2007, 16:40
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package utiles;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

 public class ModificableTableModel extends AbstractTableModel {
       
        private Object[][] data,clon_data;
        List colNames = null,colClasses=null;
        ResultSet resultSet = null;
        Connection connection = null;
        Statement stmt = null;
        int num_fil=0;
        int num_col=0;
        private boolean editable[];
        private boolean[][] cambio;
        public boolean cambiarxxx=false;
        public void cerrar(){
            try{
                connection=(resultSet.getStatement()).getConnection();
                connection.rollback();
                resultSet.close();
                connection.close();
            }catch(java.sql.SQLException e){}
        }
        
        public boolean camb(){
            return cambiarxxx;
        }
        public void poncamb(boolean afgd){
            cambiarxxx=afgd;
        }
        public void guardar_datos()throws java.sql.SQLException{
            try{
                connection=(resultSet.getStatement()).getConnection();
                /*resultSet.first();
                for(int i=0;i<num_fil;i++){
                     resultSet.updateRow();
                     resultSet.next();
                }
                 **/
                connection.commit();
                resultSet.close();
            }catch(java.sql.SQLException e){
                    
                    try{
                        connection.rollback();
                       
                    }catch(java.sql.SQLException f){
                        throw f;
                        }
                    throw e;
            }
            
        }
        
        public void rb() throws java.sql.SQLException{
            try{
                connection=(resultSet.getStatement()).getConnection();
                connection.rollback();
                
            }catch(java.sql.SQLException e){
                throw e;
            }
        }
  
        public void determina_guarda(int numero_fil,int num_colu,Object obj){
            try{
                resultSet.absolute(numero_fil);
                switch(numero_clase(obj)){
                    case 1: resultSet.updateString(num_colu,obj.toString());
                            break;
                    case 2: resultSet.updateBoolean(num_colu,(new Boolean(obj.toString())).booleanValue());
                            break;
                    case 3: resultSet.updateBigDecimal(num_colu,(new java.math.BigDecimal(obj.toString())));
                            break;
                    case 4: resultSet.updateInt(num_colu,(new Integer(obj.toString())).intValue());
                            break;
                    case 5: resultSet.updateLong(num_colu,(new Long(obj.toString())).longValue());
                            break;
                    case 6: resultSet.updateFloat(num_colu,(new Float(obj.toString())).floatValue());
                            break;
                    case 7: resultSet.updateDouble(num_colu,(new Double(obj.toString())).doubleValue());
                            break;
                    case 8: resultSet.updateShort(num_colu,(new Short(obj.toString())).shortValue());
                            break;
                    case 9: resultSet.updateObject(num_colu,obj);
                            //resultSet.updateTimeStamp(num_colu,(new java.math.BigDecimal(obj.toString())).toBigInteger());
                            break;
                    case 10: resultSet.updateObject(num_colu,obj);
                            break;
                }
            }catch(java.sql.SQLException e){}
        }
        
        public int numero_clase(Object obj){
            Class string=(new String("a")).getClass();
            Class booleano=(new Boolean(true)).getClass();
            Class bigdecimal=(new java.math.BigDecimal(0.12)).getClass();
            Class entero=(new Integer(4)).getClass();
            Class largo=(new Long(4545)).getClass();
            Class flotante=(new Float(4)).getClass();
            Class doble=(new Double(4.2)).getClass();
            Class corto=(new Short("4")).getClass();
            Class timestamp=java.sql.Timestamp.class;
            
            Class comprueba=obj.getClass();
            
            
            if(comprueba.equals(string)){
                return 1;
            }else if(comprueba.equals(booleano)){
                return 2;
            }else if(comprueba.equals(bigdecimal)){
                return 3;
            }else if(comprueba.equals(entero)){
                return 4;
            }else if(comprueba.equals(largo)){
                return 5;
            }else if(comprueba.equals(flotante)){
                return 6;
            }else if(comprueba.equals(doble)){
                return 7;
            }else if(comprueba.equals(corto)){
                return 8;
            }else if(comprueba.equals(timestamp)){
                return 9;
            }else return 10;
        }

        
        public void llenar_datos(){
            ResultSetMetaData rmd = null;  
            try {
                rmd = resultSet.getMetaData();
                num_col=rmd.getColumnCount();
                resultSet.last();
                num_fil=resultSet.getRow();
            } catch (SQLException e) {
                throw new ScrollableTableModelException ("Error obteniendo ResultSetMetaData.", e);
            }
            
            try{
                if(num_col==0 && num_fil==0){
                    data=null;
                    cambio=null;
                    return;
                } else{
                    data=new Object[num_fil][num_col];
                    cambio=new boolean[num_fil][num_col];
                    resultSet.first();
                    
                    for(int i=0;i<num_fil;i++){
                        for(int j=0;j<num_col;j++){
                            data[i][j]=resultSet.getObject(j+1);
                            cambio[i][j]=false;
                        }
                        resultSet.next();
                    }
                }
            }catch(Exception e){}
        }
        
        
             public ModificableTableModel(ResultSet rs,boolean editar[]) { 
           editable=editar;
                 if (rs == null) {
                new IllegalArgumentException("El ResultSet es nulo.");
            }
            
            Statement s = null;
            
            try {
                s = rs.getStatement();
            } catch (SQLException e) {
                throw new ScrollableTableModelException("Error obteniendo Statement desde el ResultSet.", e);
            }
            
            Connection c = null;
            
            try {
                c = s.getConnection();
            } catch (SQLException e) {
                throw new ScrollableTableModelException("Error obteniendo Connection desde el ResultSet.", e);
            }
            
           /*if (!supportsScrollInsensitive(c)) {
                throw new IllegalArgumentException("Tu conexion no soporta insensitive scroll.");
            }
            */
            if (!supportsScrollSensitive(c)) {
                throw new IllegalArgumentException("Tu conexion no soporta sensitive scroll.");
            }
            
            if (colNames != null) {
                ResultSetMetaData rmd = null;
                try {
                    rmd = rs.getMetaData();
                } catch (SQLException e) {
                    throw new ScrollableTableModelException ("Error obteniendo ResultSetMetaData.", e);
                }
                int colCount = -1;
                try {
                    colCount = rmd.getColumnCount();
                } catch (SQLException e) {
                    throw new ScrollableTableModelException ("Error obteniendo numero de columnas.", e);
                }
                if (colNames.size() != colCount) {
                    throw new IllegalArgumentException("El parametro colNames esta errado.");
                }
                this.colNames = new ArrayList(colNames);
            }
            else {
                fillColNames(rs);
            }
            
            
            this.resultSet = rs;
            this.stmt = s;
            llenar_datos();                 
        }
        
        public ModificableTableModel(ResultSet rs) { 
            editable=null;
            if (rs == null) {
                new IllegalArgumentException("El ResultSet es nulo.");
            }
            
            Statement s = null;
            
            try {
                s = rs.getStatement();
            } catch (SQLException e) {
                throw new ScrollableTableModelException("Error obteniendo Statement desde el ResultSet.", e);
            }
            
            Connection c = null;
            
            try {
                c = s.getConnection();
            } catch (SQLException e) {
                throw new ScrollableTableModelException("Error obteniendo Connection desde el ResultSet.", e);
            }
            
           /*if (!supportsScrollInsensitive(c)) {
                throw new IllegalArgumentException("Tu conexion no soporta insensitive scroll.");
            }
            */
            if (!supportsScrollSensitive(c)) {
                throw new IllegalArgumentException("Tu conexion no soporta sensitive scroll.");
            }
            
            if (colNames != null) {
                ResultSetMetaData rmd = null;
                try {
                    rmd = rs.getMetaData();
                } catch (SQLException e) {
                    throw new ScrollableTableModelException ("Error obteniendo ResultSetMetaData.", e);
                }
                int colCount = -1;
                try {
                    colCount = rmd.getColumnCount();
                } catch (SQLException e) {
                    throw new ScrollableTableModelException ("Error obteniendo numero de columnas.", e);
                }
                if (colNames.size() != colCount) {
                    throw new IllegalArgumentException("El parametro colNames esta errado.");
                }
                this.colNames = new ArrayList(colNames);
            }
            else {
                fillColNames(rs);
            }
            
            
            this.resultSet = rs;
            this.stmt = s;
            llenar_datos();                 
        }
        
        private boolean supportsScrollInsensitive(Connection con) {
        DatabaseMetaData md = null;
        try {
            md = con.getMetaData();
        } catch (SQLException e) {
            throw new ScrollableTableModelException("Error obteniendo DatabaseMetaData.", e);
        }
        try {
            return md.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
        } catch (SQLException e) {
            throw new ScrollableTableModelException("Error obteniendo DatabaseMetaData.", e);
        }
    } 
        private boolean supportsScrollSensitive(Connection con) {
        DatabaseMetaData md = null;
        try {
            md = con.getMetaData();
        } catch (SQLException e) {
            throw new ScrollableTableModelException("Error obteniendo DatabaseMetaData.", e);
        }
        try {
            return md.supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        } catch (SQLException e) {
            throw new ScrollableTableModelException("Error obteniendo DatabaseMetaData.", e);
        }
    } 
        
        public int getColumnCount() {
            return colNames.size();
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return (String)colNames.get(col);
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int columnIndex) {
           // return getValueAt(0, c).getClass();
             if (colClasses == null) {
            colClasses = new ArrayList();
            ResultSetMetaData md = null;
            try {
                md = resultSet.getMetaData();
                int colCount = md.getColumnCount();
                for (int i = 0; i < colCount; i++) {
                    try {
                        String className = md.getColumnClassName(i + 1);
                        //System.out.println(className);
                        Class c = Class.forName(className);
                        colClasses.add(c);
                    } catch (ClassNotFoundException e) {
                        throw new ScrollableTableModelException("Error obteniendo clase de columna.", e);
                    }
                }   // for i
            } catch (SQLException e) {
                throw new ScrollableTableModelException("Error obteniendo clase de columna.", e);
            }
        }
        Class c = (Class)colClasses.get(columnIndex);
        return c;
            
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
                if(editable==null){
                return true;
                }else{
                    return editable[col];
                }
            
        }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        
        public void setValueAt(Object value, int row, int col) {
            

            data[row][col] = value;
            fireTableCellUpdated(row, col);
            cambio[row][col]=true;
            cambiarxxx=true;
           try{
            resultSet.absolute(row+1);
            //resultSet.updateObject(col+1,value);
            //int a=numero_clase(col+1);
            //System.out.println("num clase= "+a);
            determina_guarda(row+1,col+1,value);
            resultSet.updateRow();
            }catch(java.sql.SQLException e){}
            
            
        }

        private void fillColNames(ResultSet resultSet) {
        if (resultSet == null) {
            throw new IllegalArgumentException("Error llenando nombres de las columnas: El ResultSet es null");
        }
        if (this.colNames == null) {
            ResultSetMetaData rsmd = null;
            try {
                rsmd = resultSet.getMetaData();
                int colCount = rsmd.getColumnCount();
                if (colCount == 0) {
                    //No haga nada!
                }
                this.colNames = new ArrayList(); 
                for (int i = 0; i < colCount; i++) {
                    String colLabel = rsmd.getColumnLabel(i+1);
                    this.colNames.add(colLabel);
                }
            } catch (SQLException e) {
                e.printStackTrace();
                throw new ScrollableTableModelException("Error obteniendo ResultSetMetadata", e);
            }
        }
    }
      
    }
    

